Vue.js 的網頁是由元件組合而成,利用 HTML 元素重複使用元件。
Components 是可以被重複使用的實體,會利用像是<button-counter>
這樣自訂的元素來使用元件。元件一樣也可傳入 data
computed
watch
methods
這些 options。
ex:
// 建立根實體/根元件
const app = Vue.createApp({})
// 定義 button-counter 全域元件
app.component('button-counter', {
data() {
return {
count: 0
}
},
template: `
<button v-on:click="count++">
You clicked me {{ count }} times.
</button>`
})
app.mount('#components-demo')
要使用幾個就有幾個,也因為每一個元件就代表一個全新的實體,當點擊這些按鈕時,每一個元件都會各自計算次數。
<div id="components-demo">
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
應用程式的架構由樹狀結構的元件組成,最常見的網頁可以被拆分成 header
、 sidebar
、 content area
這些區塊,如果要在模板中使用這些元件,就必須註冊他們,讓 Vue 知道這些元件。(元件註冊有兩種類型,global
及 local
)
在 component 中註冊 props
屬性。
ex:
const app = Vue.createApp({})
app.component('blog-post', {
props: ['title'],
template: `<h4>{{ title }}</h4>`
})
app.mount('#blog-post-demo')
<div id="blog-post-demo" class="demo">
<blog-post title="My journey with Vue"></blog-post>
<blog-post title="Blogging with Vue"></blog-post>
<blog-post title="Why Vue is so fun"></blog-post>
</div>
當值傳至 prop 時,它就會變成元件的屬性,在模板中也就可以取用到這個值。
父元件可以透過v-on
或是 @
監聽子元件的所有事件,而子元件可以使用內建的 $emit
方法發送事件名稱。
ex:
const app = Vue.createApp({
data() {
return {
posts: [
{ id: 1, title: 'My journey with Vue'},
{ id: 2, title: 'Blogging with Vue'},
{ id: 3, title: 'Why Vue is so fun'}
],
postFontSize: 1 // 父元件增加 postFontSize 的 data 屬性
}
}
})
// 註冊 blog-post 元件
app.component('blog-post', {
props: ['title'],
template: `
<div class="blog-post">
<h4>{{ title }}</h4>
// 發送一個名稱為 enlargeText 的事件出去
<button @click="$emit('enlargeText')">
Enlarge text
</button>
</div>
`
})
app.mount('#blog-posts-events-demo')
<div id="blog-posts-events-demo" class="demo">
<!-- postFontSize 值寫入樣式中,控制所有文章的字體大小 -->
<div :style="{ fontSize: postFontSize + 'em' }">
<blog-post
v-for="post in posts"
:key="post.id"
:title="post.title"
@enlarge-text="postFontSize += 0.1"
></blog-post>
</div>
</div>
元件之間的資料傳遞:
Props in, Event out
不需要使用 export/import,任何地方都可以使用註冊在全域的元件。
ex:
const app = Vue.createApp({})
// 元件註冊在 app 上 (app 為根實體或稱根元件)
app.component('component-a', {
/* ... */
})
app.component('component-b', {
/* ... */
})
app.component('component-c', {
/* ... */
})
// 掛載在 #app 上
app.mount('#app')
<div id="app">
<component-a></component-a>
<component-b></component-b>
<component-c></component-c>
</div>
不推薦把元件都註冊進全域中,因為未使用到的元件也會一併被打包,增加不必要的下載量。
ex:
// 元件先以物件方式定義
const ComponentA = {
/* ... */
}
const ComponentB = {
/* ... */
}
const ComponentC = {
/* ... */
}
// 使用 components option 註冊
const app = Vue.createApp({
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
每日一句:
即使長這麼大,終究無法適應收假的心情